using System;
using System.Collections.Generic;

namespace GameKit.Core.Context
{
    public class Context : IContext
    {
        public string Name { get; set; }

        private readonly Dictionary<Type, object> _services = new();
        private readonly Dictionary<string, object> _tagServices = new();

        public Context(string name)
        {
            Name = name;
        }

        public virtual void Initialize()
        {
        }

        /// <summary>
        /// 注册一个服务（支持普通C#对象或MonoBehaviour）
        /// </summary>
        public void Register<T>(T instance)
        {
            if (instance == null)
            {
                Log.Error($"尝试注册空实例：{typeof(T).Name}");
                return;
            }

            _services[typeof(T)] = instance;
        }

        public void Register(string tag, object instance)
        {
            if (!_tagServices.TryAdd(tag, instance))
            {
                throw new Exception($"Tag already registered: {tag}");
            }
        }

        /// <summary>
        /// 注销某个服务
        /// </summary>
        public void Unregister<T>()
        {
            _services.Remove(typeof(T));
        }

        public void Unregister(string tag)
        {
            _tagServices.Remove(tag);
        }

        /// <summary>
        /// 获取服务实例
        /// </summary>
        public T Get<T>()
        {
            if (_services.TryGetValue(typeof(T), out var obj))
            {
                return (T)obj;
            }

            return default;
        }

        public bool TryGet<T>(out T instance)
        {
            if (_services.TryGetValue(typeof(T), out var obj))
            {
                instance = (T)obj;
                return true;
            }

            instance = default;
            return false;
        }

        public T Get<T>(string tag)
        {
            if (_services.TryGetValue(typeof(T), out var obj))
            {
                return (T)obj;
            }

            return default;
        }

        public bool TryGet<T>(string tag, out T instance)
        {
            if (_tagServices.TryGetValue(tag, out var obj))
            {
                instance = (T)obj;
                return true;
            }

            instance = default;
            return false;
        }

        /// <summary>
        /// 清空所有注册
        /// </summary>
        public virtual void Dispose()
        {
            _services.Clear();
        }
    }
}